home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / util / cli / MCommands_1_2.lha / Src / for.c < prev    next >
C/C++ Source or Header  |  1992-09-02  |  6KB  |  248 lines

  1. #define __USE_SYSBASE
  2.  
  3. #include <exec/types.h>
  4. #include <exec/execbase.h>
  5. #include <exec/memory.h>
  6. #include <dos/rdargs.h>
  7. #include <dos/dosasl.h>
  8. #include <dos/dosextens.h>
  9. #include <dos/dostags.h>
  10. #include <utility/tagitem.h>
  11. #include <support/types.h>
  12. #include <support/exec.h>
  13. #include <support/dos.h>
  14.  
  15. #include <string.h>
  16.  
  17. #include <proto/exec.h>
  18. #include <proto/dos.h>
  19.  
  20. #include "for.rev.h"
  21.  
  22. #define DOS_NAME        "dos.library"
  23. #define DOS_VERN         37L
  24.  
  25. #define TEMPLATE        "FILE/M,DO/K/F,ALL/S,NOQUOTE=NQ/S"
  26.  
  27. #define DEF_COMM        "%S"
  28.  
  29. STATIC CONST TEXT VersionString[]=
  30.     VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
  31.  
  32. #define OPT_FILE        0
  33. #define OPT_DO            1
  34. #define OPT_ALL            2
  35. #define OPT_NQ            3
  36. #define OPT_COUNT        4
  37.  
  38. #define NAME_SIZE        32            /* File's name */
  39. #define COMM_SIZE        1024        /* Unexpanded command */
  40. #define PRSD_SIZE        1024        /* Expanded command */
  41. #define PATH_SIZE        256            /* For file's path */
  42.  
  43. #define CommString    (Opts[OPT_DO] ? (STRPTR)Opts[OPT_DO] : RawComm)
  44.  
  45. STATIC BOOL PrepComm(STRPTR format, STRPTR buffer, ULONG buffSize,
  46.                                             STRPTR name, STRPTR path, BOOL quote);
  47. STATIC BOOL CopyComm(STRPTR *args, STRPTR buffer, ULONG buffSize);
  48.  
  49. ULONG For(VOID)
  50. {
  51.     struct ExecBase *SysBase=*((struct ExecBase **)4);
  52.     struct DosLibrary *DOSBase;
  53.  
  54.     STATIC CONST struct TagItem CommandTags[]=
  55.     {
  56.         {SYS_UserShell,TRUE},
  57.         {TAG_DONE,0}
  58.     };
  59.     STATIC CONST STRPTR DefFile[]={"#?",NULL};
  60.  
  61.     struct RDArgs *Args;
  62.     struct AnchorPath *Anchor;
  63.     LONG Opts[OPT_COUNT];
  64.     ULONG I,TempRC,RC=RETURN_FAIL;
  65.     CHAR FName[NAME_SIZE];
  66.     STRPTR RawComm,ParsedComm,CurArg,*ArgPtr;
  67.     BPTR CurrLock,OldLock;
  68.     BOOL ErrOccured=FALSE,MultiFile=TRUE;
  69.  
  70.     unless(DOSBase=(struct DosLibrary *)OpenLibrary(DOS_NAME,DOS_VERN))
  71.     {
  72.         SetResult2(ERROR_INVALID_RESIDENT_LIBRARY);
  73.         goto InvalidDOS;
  74.     }
  75.  
  76.     unless(Anchor=AllocVec(sizeof(struct AnchorPath)+PATH_SIZE,MEMF_CLEAR))
  77.     {
  78.         PrintFault(IoErr(),NULL);                                /* Inform user */
  79.         goto NoMemory1;
  80.     }
  81.     Anchor->ap_BreakBits=SIGBREAKF_CTRL_C;        /* Allow break */
  82.     Anchor->ap_Strlen=PATH_SIZE;
  83.  
  84.     unless(RawComm=AllocVec(COMM_SIZE+PRSD_SIZE,MEMF_CLEAR))
  85.     {
  86.         PrintFault(IoErr(),NULL);                                /* Inform user */
  87.         goto NoMemory2;
  88.     }
  89.     ParsedComm=RawComm+COMM_SIZE;
  90.  
  91.     clear(&Opts);
  92.     unless(Args=ReadArgs(TEMPLATE,Opts,NULL))
  93.     {
  94.         PrintFault(IoErr(),NULL);                                /* Inform user */
  95.         goto NoArgs;
  96.     }
  97.     ArgPtr=Opts[OPT_FILE] ? (STRPTR *)Opts[OPT_FILE] : DefFile;
  98.  
  99.     unless(Opts[OPT_DO])                                                /* 'DO' not specified, */
  100.     {                                                                                        /* This is <file>+<command> */
  101.         if(ArgPtr[1])                                                            /* Only one file patern specified */
  102.         {
  103.             unless(CopyComm(ArgPtr,RawComm,COMM_SIZE))    /* Copy patterns to command */
  104.             {
  105.                 CauseIoErr(ERROR_LINE_TOO_LONG,NULL);
  106.                 goto Exit;
  107.             }
  108.             MultiFile=FALSE;                                                /* There is only one file */
  109.         }
  110.         else                                                                            /* Multiple patterns */
  111.             stpcpy(RawComm,DEF_COMM);                                /* Set command to "run" */
  112.     }
  113.  
  114.     for(I=0; (CurArg=*ArgPtr++) && (I==0 || MultiFile); I++)
  115.     {
  116.         clear(Anchor);
  117.         Anchor->ap_BreakBits=SIGBREAKF_CTRL_C;        /* Allow break */
  118.         Anchor->ap_Strlen=PATH_SIZE;                            /* We have a path buffer */
  119.         TempRC=MatchFirst(CurArg,Anchor);
  120.         while(TempRC==0)
  121.         {
  122.             stpcpy(FName,Anchor->ap_Info.fib_FileName);
  123.             if(Anchor->ap_Info.fib_DirEntryType>=0)
  124.             {
  125.                 if(Opts[OPT_ALL])
  126.                 {
  127.                     if(!ftst(Anchor->ap_Flags,APF_DIDDIR))
  128.                         fset(Anchor->ap_Flags,APF_DODIR);
  129.                     fclr(Anchor->ap_Flags,APF_DIDDIR);
  130.                 }
  131.                 goto Next;    
  132.             }
  133.             CurrLock=DupLock(Anchor->ap_Current->an_Lock);
  134.             OldLock=CurrentDir(CurrLock);
  135.             if(PrepComm(CommString,ParsedComm,PRSD_SIZE,
  136.                                     FName,Anchor->ap_Buf,!Opts[OPT_NQ]))
  137.             {
  138.                 if(System(ParsedComm,CommandTags))    /* An error */
  139.                 {
  140.                     ErrOccured=TRUE;
  141.                     PrintFault(IoErr(),FName);
  142.                 }
  143.             }
  144.             else
  145.             {
  146.                 ErrOccured=TRUE;
  147.                 CauseIoErr(ERROR_LINE_TOO_LONG,NULL);
  148.             }
  149.             CurrentDir(OldLock);
  150.             UnLock(CurrLock);
  151. Next:
  152.             TempRC=MatchNext(Anchor);
  153.         }
  154.         if(TempRC==ERROR_NO_MORE_ENTRIES)
  155.             RC=(ErrOccured ? RETURN_ERROR : RETURN_OK);
  156.         else
  157.         {
  158.             PrintFault(TempRC,NULL);
  159.             RC=(TempRC==ERROR_BREAK ? RETURN_WARN : RETURN_FAIL);
  160.         }
  161.         MatchEnd(Anchor);
  162.         if(TempRC==ERROR_BREAK)
  163.             break;
  164.     }
  165.  
  166. Exit:
  167.     FreeArgs(Args);
  168. NoArgs:
  169.     FreeVec(RawComm);
  170. NoMemory2:
  171.     FreeVec(Anchor);
  172. NoMemory1:
  173.     CloseLibrary((struct Library *)DOSBase);
  174. InvalidDOS:
  175.     return(RC);
  176. }
  177.  
  178. STATIC BOOL PrepComm(STRPTR format, STRPTR buffer, ULONG buffSize,
  179.                                             STRPTR name, STRPTR path, BOOL quote)
  180. {
  181.     ULONG NameLen=strlen(name),PathLen=strlen(path),Len;
  182.     CHAR CurrChar;
  183.     STRPTR Arg,HighBuffer=buffer+buffSize-1;
  184.  
  185.     memset(buffer,0,buffSize);        /* Clear buffer */
  186.     while(CurrChar=*format++)
  187.     {
  188.         if(buffer<HighBuffer)                /* The char will fit */
  189.             *buffer=CurrChar;
  190.         else
  191.             return(FALSE);
  192.  
  193.         if(CurrChar=='%')
  194.         {
  195.             switch(*format)
  196.             {
  197.                 case 's':
  198.                 case 'S':
  199.                     Len=NameLen;
  200.                     Arg=name;
  201.                     break;
  202.                 case 'p':
  203.                 case 'P':
  204.                     Len=PathLen;
  205.                     Arg=path;
  206.                     break;
  207.                 case '%':
  208.                     format++;
  209.                 default:
  210.                     buffer++;
  211.                     continue;
  212.             }
  213.             if(buffer+Len+(quote ? 2 : 0)<HighBuffer)
  214.             {
  215.                 if(quote)
  216.                     *buffer++='"';
  217.                 buffer=stpcpy(buffer,Arg);    /* Insert arg */
  218.                 if(quote)
  219.                     *buffer++='"';
  220.                 format++;                                        /* Skip control char */
  221.             }
  222.             else
  223.                 return(FALSE);
  224.         }
  225.         else
  226.             buffer++;
  227.     }
  228.     return(TRUE);
  229. }
  230.  
  231. STATIC BOOL CopyComm(STRPTR *args, STRPTR buffer, ULONG buffSize)
  232. {
  233.     ULONG I;
  234.     STRPTR Arg,HighBuffer=buffer+buffSize-1;
  235.     
  236.     memset(buffer,0,buffSize);                        /* Clear buffer */
  237.     for(I=1; Arg=args[I]; I++)                        /* While there is an arg to add */
  238.         if(buffer+strlen(Arg)+1<HighBuffer)    /* This arg will fit */
  239.         {
  240.             if(I>1)                                                        /* Not first arg */
  241.                 *buffer++=' ';                                    /* Add one separating space */
  242.             buffer=stpcpy(buffer,Arg);                /* Copy this arg */
  243.         }
  244.         else
  245.             return(FALSE);
  246.     return(TRUE);
  247. }
  248.